home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ZED3DSRC.ZIP / OBJECTS.C < prev    next >
C/C++ Source or Header  |  1995-06-19  |  5KB  |  333 lines

  1. #include <stdlib.h>
  2. #include <objects.h>
  3.  
  4.  
  5. pointcollection *alloc_pointcollection(int numpoints)
  6.     {
  7.     pointcollection *p;
  8.  
  9.     p=malloc(sizeof(pointcollection)); /* try to allocate */
  10.     if(!p)
  11.         return 0; /* if fail to allocate, return error */
  12.  
  13.     p->vertex=malloc(sizeof(point)*numpoints);
  14.         /* Allocate room for the vertices in the pointcollection */
  15.     if(!p->vertex)
  16.         {
  17.         free_pointcollection(p); /* if failure to allocate free it and */
  18.         return 0; /* return error */
  19.         }
  20.  
  21.     p->numpoints=numpoints; /* put the number of points in the object
  22.                                struct */
  23.  
  24.     return p; /* return the newly created object struct */
  25.     }
  26.  
  27.  
  28.  
  29.  
  30. void free_pointcollection(pointcollection *p)
  31.     {
  32.     if(p) /* if p is not the null object */
  33.         {
  34.         if(p->vertex) /* if p->vertex exists */
  35.             free(p->vertex); /* destroy it */
  36.         /* just for safety, overwrite all pointers with zeroes */
  37.         p->vertex=0;
  38.  
  39.         free(p);
  40.         }
  41.     }
  42.  
  43.  
  44.  
  45. facecollection *alloc_facecollection(int numfaces)
  46.     {
  47.     facecollection *f;
  48.     long a;
  49.  
  50.     f=malloc(sizeof(facecollection));
  51.     if(!f)
  52.         return 0;
  53.  
  54.     f->face=malloc(sizeof(face)*numfaces);
  55.     if(!f->face)
  56.         {
  57.         free_facecollection(f);
  58.         return 0;
  59.         }
  60.  
  61.     for(a=0;a<numfaces;a++)
  62.         f->face[a].index=0;
  63.  
  64.     f->numfaces=numfaces;
  65.  
  66.     return f;
  67.     }
  68.  
  69.  
  70.  
  71.  
  72. void free_facecollection(facecollection *f)
  73.     {
  74.     long a;
  75.  
  76.     if(f)
  77.         {
  78.         if(f->face)
  79.             {
  80.             for(a=0;a<f->numfaces;a++)
  81.                 {
  82.                 if(f->face[a].index)
  83.                     {
  84.                     free(f->face[a].index);
  85.                     f->face[a].index=0;
  86.                     }
  87.                 }
  88.             free(f->face);
  89.             f->face=0;
  90.             }
  91.         free(f);
  92.         }
  93.     }
  94.  
  95.  
  96.  
  97.  
  98. object *alloc_object(long numpoints, long numfaces)
  99.     {
  100.     object *o;
  101.  
  102.     o=malloc(sizeof(object));
  103.     if(!o)
  104.         return 0;
  105.  
  106.     o->pts_data=alloc_pointcollection(numpoints);
  107.     o->face_data=alloc_facecollection(numfaces);
  108.     o->usecount=1;
  109.  
  110.     if((!o->pts_data)||(!o->face_data))
  111.         {
  112.         free_object(o);
  113.         return 0;
  114.         }
  115.  
  116.     return o;
  117.     }
  118.  
  119.  
  120.  
  121.  
  122. void free_object(object *o)
  123.     {
  124.     if(o)
  125.         {
  126.         o->usecount--;
  127.  
  128.         if(o->usecount==0)
  129.             {
  130.             free_pointcollection(o->pts_data);
  131.             o->pts_data=0;
  132.             free_facecollection(o->face_data);
  133.             o->face_data=0;
  134.             }
  135.         }
  136.     }
  137.  
  138.  
  139.  
  140. object *clone_object(object *o)
  141.     {
  142.     o->usecount++;
  143.     return o;
  144.     }
  145.  
  146.  
  147.  
  148. REAL compute_2area(face *f, point *p, int axis1, int axis2)
  149.     {
  150.     long a,b,c,x,y,z;
  151.     REAL area;
  152.  
  153.     b=f->index[f->numpoints-1];
  154.     area=floattoreal(0.0);
  155.     for(a=0;a<f->numpoints;a++)
  156.         {
  157.         /* for each edge, compute signed area of trapeze */
  158.  
  159.         c=f->index[a];
  160.         /* edge goes from point #b to point #c */
  161.  
  162.         area+=mul(
  163.             p[c].location[axis2]+p[b].location[axis2],
  164.             p[c].location[axis1]-p[b].location[axis1]);
  165.  
  166.         b=c;
  167.         }
  168.  
  169.     return area;
  170.     }
  171.  
  172.  
  173.  
  174. void normalize_object(object *o)
  175.     {
  176.     face *f;
  177.     long a,b,c;
  178. #ifdef __vertexnormals__
  179.     point *p;
  180. #endif
  181.  
  182.  
  183. #ifdef __vertexnormals__
  184.     p=o->pts_data->vertex;
  185.     for(a=0;a<o->pts_data->numpoints;a++,p++)
  186.         {
  187.         vec_normalize(p->normal);
  188.         }
  189. #endif
  190.  
  191.     f=o->face_data->face;
  192.     for(a=0;a<o->face_data->numfaces;a++,f++)
  193.         {
  194.         vec_normalize(f->normal);
  195.         }
  196.  
  197.     fix_D(o);
  198.     }
  199.  
  200.  
  201.  
  202. void init_normals(object *o)
  203.     {
  204.     long a,b,c,x,y,z;
  205.     face *f;
  206.     point *p;
  207.  
  208.     p=o->pts_data->vertex;
  209.     f=o->face_data->face;
  210.  
  211.     for(a=0;a<o->pts_data->numpoints;a++)
  212.         {
  213. #ifdef __vertexnormals__
  214.         initvector(p[a].normal,0,0,0);
  215. #endif
  216.         p[a].clipping=0;
  217.         }
  218.  
  219.     for(a=0;a<o->face_data->numfaces;a++,f++)
  220.         {
  221.         f->normal[0]=compute_2area(f,p,1,2);
  222.         f->normal[1]=compute_2area(f,p,2,0);
  223.         f->normal[2]=compute_2area(f,p,0,1);
  224.  
  225.         for(b=0;b<f->numpoints;b++)
  226.             {
  227. #ifdef __vertexnormals__
  228.             vec_add(p[f->index[b]].normal,p[f->index[b]].normal,f->normal);
  229. #endif
  230.             p[f->index[b]].clipping++;
  231.             }
  232.  
  233.  
  234.         }
  235.  
  236.     fix_D(o);
  237.     }
  238.  
  239.  
  240. void fix_D(object *o)
  241.     {
  242.     face *f;
  243.     point *p;
  244.     long a;
  245.  
  246.     p=o->pts_data->vertex;
  247.     f=o->face_data->face;
  248.  
  249.     for(a=0;a<o->face_data->numfaces;a++,f++)
  250.         f->D=vec_dot(f->normal,p[*f->index].location);
  251.     }
  252.  
  253.  
  254.  
  255.  
  256. int init_facepts(face *f, long numpoints)
  257.     {
  258.     f->index=malloc(sizeof(long)*numpoints);
  259.     if(f->index==0)
  260.         return -1;
  261.  
  262.     f->numpoints=numpoints;
  263.     return 0;
  264.     }
  265.  
  266.  
  267.  
  268. int make_tetrahedron(object *o)
  269.     {
  270.     face *f;
  271.     point *p;
  272.     long a,b,c,doit;
  273.     REAL A,B,C,D;
  274.  
  275.     f=o->face_data->face;
  276.  
  277.     for(a=0;a<4;a++,f++)
  278.         {
  279.         if(init_facepts(f,3))
  280.             return 0;
  281.         }
  282.  
  283.  
  284.     f=o->face_data->face;
  285.  
  286.     for(a=0;a<4;a++,f++)
  287.         {
  288.         for(b=0,c=0;b<3;b++,c++)
  289.             {
  290.             if(c==a)
  291.                 c++;
  292.             f->index[b]=c;
  293.             }
  294.         }
  295.  
  296.     p=o->pts_data->vertex;
  297.  
  298.     init_normals(o);
  299.  
  300.     doit=0;
  301.  
  302.     p=o->pts_data->vertex;
  303.     f=o->face_data->face;
  304.     for(a=0;a<4;a++,f++)
  305.         {
  306.         for(b=0,A=floattoreal(0.0);b<4;b++)
  307.             {
  308.             B=vec_dot(f->normal,p[b].location);
  309.             B-=f->D;
  310.             C=mul(B,B);
  311.             if(C>A)
  312.                 {
  313.                 A=C;
  314.                 D=B;
  315.                 }
  316.             }
  317.         if(A<floattoreal(0.001))
  318.             {
  319.             doit=-1;
  320.             break;
  321.             }
  322.         if(D>0)
  323.             vec_mul_scl(f->normal,f->normal,floattoreal(-1));
  324.         }
  325.  
  326.     fix_D(o);
  327.  
  328.     return doit;
  329.     }
  330.  
  331.  
  332.  
  333.